// Auteur : Simon-Pierre Boucher — contact@spboucher.ai // Profil public d'un membre (opt-in) — groupe-ka.com/u/{ka_id}. // Affiche nom, photo, statut, bio, emploi, ville, âge, site et réseaux — // JAMAIS le courriel ni le téléphone. 404 indistinct si privé/inexistant. import type { Metadata } from "next"; import { db, parseSocials, ageFromBirthDate, type UserRow, } from "@/lib/db"; import { roleCard } from "@/lib/roles"; export const metadata: Metadata = { title: "Profil de membre | Groupe KA", description: "Profil public d'un membre du Groupe KA.", }; export const dynamic = "force-dynamic"; function fmtDate(iso: string | null): string { if (!iso) return "—"; const d = new Date(iso.includes("T") ? iso : iso.replace(" ", "T") + "Z"); if (Number.isNaN(d.getTime())) return "—"; return d .toLocaleDateString("fr-CA", { month: "long", year: "numeric" }); } const SOCIAL_LABELS: Record = { instagram: "Instagram", facebook: "Facebook", x: "X", linkedin: "LinkedIn", tiktok: "TikTok", youtube: "YouTube", }; function socialHref(key: string, value: string): string { if (/^https?:\/\//i.test(value)) return value; const handle = value.replace(/^@/, ""); const base: Record = { instagram: "https://instagram.com/", facebook: "https://facebook.com/", x: "https://x.com/", linkedin: "https://www.linkedin.com/in/", tiktok: "https://www.tiktok.com/@", youtube: "https://www.youtube.com/", }; return (base[key] ?? "https://") + handle; } export default async function ProfilPublic({ params, }: { params: Promise<{ kaId: string }>; }) { const { kaId } = await params; const clean = /^ka-\d{10}$/.test(kaId) ? kaId : null; const row = clean ? (db.prepare("SELECT * FROM users WHERE ka_id = ?").get(clean) as | UserRow | undefined) : undefined; // privé ou inexistant : indistinguable, volontairement if (!row || !row.public) { return (

Profil de membre

Profil introuvable

Ce profil n'existe pas ou n'est pas public.

); } const socials = parseSocials(row.socials); const age = ageFromBirthDate(row.birth_date); const facts: [string, string][] = [ ...(row.job_title ? ([["Emploi", row.company ? `${row.job_title} · ${row.company}` : row.job_title]] as [string, string][]) : row.company ? ([["Entreprise", row.company]] as [string, string][]) : []), ...(row.city ? ([["Ville", row.city]] as [string, string][]) : []), ...(age !== null ? ([["Âge", `${age} ans`]] as [string, string][]) : []), ["Membre depuis", fmtDate(row.created_at)], ["KA-ID", row.ka_id ?? "—"], ]; return (

Profil de membre · Groupe KA

{row.avatar_url ? ( // eslint-disable-next-line @next/next/no-img-element {`Photo ) : ( {row.name.charAt(0).toUpperCase()} )}

{row.name}

{roleCard(row.role) && (

{roleCard(row.role)}

)} {row.bio && (

{row.bio}

)}
{facts.map(([label, value], i) => (
{label} {value}
))}
{(row.website || Object.keys(socials).length > 0) && (
{row.website && ( 🌐 Site web )} {Object.entries(socials).map(([k, v]) => ( {SOCIAL_LABELS[k] ?? k} ))}
)}

Profil publié volontairement par ce membre —{" "} vérifier son KA-ID . Courriel et téléphone jamais affichés.

); }